package tools

import (
	"encoding/json"
	"fmt"
	"math"
	"mygo/app/models"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"
)

// Max 计算最大值
func Max[T models.Num](a, b T) float64 {
	if float64(a) > float64(b) {
		return float64(a)
	}
	return float64(b)
}

// StrToFloat64 最常用的集中类型肯定是 string,float64,int 浮点必须是float64，int可以用int()转换
// 字符串转换为float64
func StrToFloat64(str string) float64 {
	var result float64
	result, _ = strconv.ParseFloat(str, 64)
	return result
}

// StrToInt 字符串转换为int
func StrToInt(str string) int {
	var result int
	result, _ = strconv.Atoi(str)
	return result
}

// Float64ToStr float64转换为字符串
func Float64ToStr(f float64) string {
	return strconv.FormatFloat(f, 'f', -1, 64)
}

// IntToStr int转换为字符串
func IntToStr(i int) string {
	return strconv.Itoa(i)
}

// 对float64四舍五入取整
func Round(f float64) int {
	return int(f + 0.5)
}

// 计算[]float64的最大值和最小值和对应的索引
func MaxAndMinAndIndex(arr []float64) (max, min float64, maxIndex, minIndex int) {
	max = arr[0]
	min = arr[0]
	maxIndex = 0
	minIndex = 0
	for i, v := range arr {
		if v > max {
			max = v
			maxIndex = i
		}
		if v < min {
			min = v
			minIndex = i
		}
	}
	return max, min, maxIndex, minIndex
}

// float64保留n位小数
func Float64ToFixed(f float64, n int) float64 {
	return math.Trunc(f*math.Pow10(n)+0.5) / math.Pow10(n)
}

func Float64ToFixedStr(f float64, n int) string {
	if f == 0 {
		return ""
	}
	formatted := fmt.Sprintf("%."+strconv.Itoa(n)+"f", f)
	return formatted
}

func Float64ToFixedStrZ(f float64, n int, emp string) string {
	if f == 0 {
		return emp
	}
	formatted := fmt.Sprintf("%."+strconv.Itoa(n)+"f", f)
	return formatted
}

// 获取字符串中的数字
func GetNum(str string) []int {
	var result []int
	for _, v := range str {
		if v >= 48 && v <= 57 {
			result = append(result, int(v-48))
		}
	}
	return result
}

// 获取字符串中的数字，包括小数
func GetNumFloat(str string) []float64 {
	var result []float64
	for _, v := range str {
		if v >= 48 && v <= 57 {
			result = append(result, float64(v-48))
		}
	}
	return result
}

// 计算[]florat64平均数
func Average(arr []float64) float64 {
	var sum float64
	for _, v := range arr {
		sum += v
	}
	return sum / float64(len(arr))
}

func GetNumFloat64(str string) (matches []float64) {
	pattern := `\d+\.\d+`

	re := regexp.MustCompile(pattern)
	//matches := re.FindAllString(str, -1)
	matchesStr := re.FindAllString(str, -1)
	for _, v := range matchesStr {
		matches = append(matches, StrToFloat64(v))
	}
	return matches

	//if len(matches) >= 2 {
	//	fmt.Println(matches[0])
	//	fmt.Println(matches[1])
	//} else {
	//	fmt.Println("未找到匹配的数字")
	//}
}

// MaxFloat64 求数组中的最大值
func MaxFloat64(arr []float64) float64 {
	var mmm float64
	mmm = arr[0]
	for _, v := range arr {
		if v > mmm {
			mmm = v
		}
	}
	return mmm
}

// TrimSpace 去除字符串中的空格
func TrimSpace(str string) string {
	return strings.Replace(str, " ", "", -1)
}

// SliceChinese 对中文字符进行切片
func SliceChinese(str string, startIndex, endIndex int) string {
	runes := []rune(str)
	// 计算切片的起始和结束字节索引
	startByteIndex := utf8.RuneCountInString(str[:startIndex])
	endByteIndex := utf8.RuneCountInString(str[:endIndex])
	// 对切片进行操作
	slicedRunes := runes[startByteIndex:endByteIndex]
	// 将切片转换回字符串
	slicedStr := string(slicedRunes)
	return slicedStr
}

// TimeStampToDate
func TimeStampToDate(timestamp int64) string {
	tm := time.Unix(timestamp, 0)
	return tm.Format("2006-01-02 15:04:05")
}

// SortFloat64
func SortFloat64(arr []float64) []float64 {
	for i := 0; i < len(arr); i++ {
		for j := 0; j < len(arr)-1-i; j++ {
			if arr[j+1] < arr[j] {
				arr[j+1], arr[j] = arr[j], arr[j+1]
			}
		}
	}
	return arr
}

// /IsNum
func IsNum(str string) bool {
	_, err := strconv.ParseFloat(str, 64)
	return err == nil
}

// 在一段字符串中删除类似 “（蓝色）” 的内容
func DelColor(str string) string {
	re := regexp.MustCompile(`（.*）`)
	return re.ReplaceAllString(str, "")
}

// GetDayGap
func GetDayGap(dateStart, dateEnd string) int {
	//获取间隔了多少天
	startTime, _ := time.Parse("2006-01-02", dateStart)
	endTime, _ := time.Parse("2006-01-02", dateEnd)
	//fmt.Println(startTime)
	//fmt.Println(endTime)
	dayGap := int(endTime.Sub(startTime).Hours()/24) + 1
	return dayGap
}

// GetNextDayStr
func GetNextDayStr(date string, dayGap int) string {
	tm, _ := time.Parse("2006-01-02", date)
	tm = tm.AddDate(0, 0, dayGap)
	return tm.Format("2006-01-02")
}

// 获取两个日期之间差多少小时 格式为 2006-01-02 15:04
func GetHourGap(dateStart, dateEnd string) int {
	startTime, _ := time.Parse("2006-01-02 15:04", dateStart)
	endTime, _ := time.Parse("2006-01-02 15:04", dateEnd)
	hourGap := int(endTime.Sub(startTime).Hours())
	return hourGap
}

func TwoCorrelation(a, b any) bool {
	//	判断a和b时候存在关联关系
	//	如果a是字符串，b是字符串数组，判断b中是否有包含a的字符串；如果a是字符串数组，b是字符串，判断a中是否有包含b的字符串
	//	如果a是字符串数组，b是字符串数组，判断a中是否有包含b的字符串，或者b中是否有包含a的字符串；如果a是字符串，b是字符串，判断a和b是否相等

	if a == nil || b == nil {
		return false
	}

	if reflect.TypeOf(a).String() == "string" && reflect.TypeOf(b).String() == "[]string" {
		for _, v := range b.([]string) {
			if strings.Contains(v, a.(string)) || strings.Contains(a.(string), v) {
				return true
			}
		}
		return false
	}

	if reflect.TypeOf(a).String() == "[]string" && reflect.TypeOf(b).String() == "string" {
		for _, v := range a.([]string) {
			if strings.Contains(v, b.(string)) || strings.Contains(b.(string), v) {
				return true
			}
		}
		return false
	}

	if reflect.TypeOf(a).String() == "[]string" && reflect.TypeOf(b).String() == "[]string" {
		for _, v := range a.([]string) {
			for _, v2 := range b.([]string) {
				if strings.Contains(v, v2) || strings.Contains(v2, v) {
					return true
				}
			}
		}
		return false
	}

	if reflect.TypeOf(a).String() == "string" && reflect.TypeOf(b).String() == "string" {
		if strings.Contains(a.(string), b.(string)) || strings.Contains(b.(string), a.(string)) {
			return true
		}
		return false
	}

	return false
}

// 替换字符串中格式为 1.2 的数字 为[]float64中的值
func ReplaceFloat64(str string, arr []float64) string {
	re := regexp.MustCompile(`\d+\.\d+`)
	matches := re.FindAllString(str, -1)
	for i, v := range matches {
		str = strings.Replace(str, v, Float64ToFixedStr(arr[i], 1), -1)
	}
	return str
}

// 将字符串中的数字减1并且替换”明天“，”后天“，”大后天“
func ReplaceNum(str string, offset int) string {

	//遍历字符串，将字符串中的数字减1
	for i, v := range str {
		if v >= 48 && v <= 57 {
			//	对应位置上的数字减1
			str = str[:i] + IntToStr(StrToInt(str[i:i+1])+offset) + str[i+1:]
		}
	}

	str = strings.Replace(str, "明天", "", -1)
	str = strings.Replace(str, "大后天", "", -1)
	str = strings.Replace(str, "后天", "", -1)
	str = strings.Replace(str, "▽", "级阵风", -1)
	strArr := strings.Split(str, "，")
	var strResult string
	if len(strArr) == 1 {
		strResult = strArr[0] + "级"
	} else {
		strResult = strArr[0] + "级，" + strArr[1] + "级"
	}
	return strResult
}

// 对风速进行减小半级处理 7-8▽9->7▽8;7-8->7▽8;7▽8->6-7▽8
func ModifyWindSpeed(speedStr, decrease string) string {
	decreaseArr := strings.Split(decrease, ".")
	intDes := 0
	if len(decreaseArr) == 1 {
		intDes = StrToInt(decrease)
	} else {
		intDes = StrToInt(decreaseArr[0])
	}
	for i, v := range speedStr {
		if v >= 48 && v <= 57 {
			//speedStr = strings.Replace(speedStr, string(v), strconv.Itoa(int(v-48-int32(intDes))), 1)
			speedStr = speedStr[:i] + IntToStr(StrToInt(string(v))-intDes) + speedStr[i+1:]
		}
	}

	if len(decreaseArr) == 1 {
		return speedStr
	}

	//	减小半级处理  3-4；3▽4；3-4▽5；

	//正则判断格式是否为8▽9-10  变为7-8
	re := regexp.MustCompile(`^\d+▽\d+-\d+$`)
	matches := re.FindAllString(speedStr, -1)
	if len(matches) > 0 {
		arr := strings.Split(strings.Split(matches[0], "-")[0], "▽")
		speedStr = IntToStr(StrToInt(arr[0])-1) + "-" + IntToStr(StrToInt(arr[1])-1)
		return speedStr
	}

	//正则判断格式是否为8-9▽10  变为8-9
	re = regexp.MustCompile(`^\d+-\d+▽\d+$`)
	matches = re.FindAllString(speedStr, -1)
	if len(matches) > 0 {
		speedStr = strings.Split(matches[0], "▽")[0]
		return speedStr
	}

	//正则判断格式是否为8-9  变为8▽9
	re = regexp.MustCompile(`^\d+-\d+$`)
	matches = re.FindAllString(speedStr, -1)
	if len(matches) > 0 {
		//speedStr = strings.Replace(speedStr, matches[0], strings.Split(matches[0], "-")[0]+"▽"+strings.Split(matches[0], "-")[1], -1)
		arr := strings.Split(matches[0], "-")
		speedStr = arr[0] + "▽" + arr[1]
		return speedStr
	}

	//正则判断格式是否为8▽9  变为7-8
	re = regexp.MustCompile(`^\d+▽\d+$`)
	matches = re.FindAllString(speedStr, -1)
	if len(matches) > 0 {
		arr := strings.Split(matches[0], "▽")
		speedStr = IntToStr(StrToInt(arr[0])-1) + "-" + IntToStr(StrToInt(arr[1])-1)
		return speedStr
	}

	return speedStr
}

//获取正则匹配的字符串数组
//func MatchWind(speedStr string) string {
//	reArr:=[]string{}
//}

// JsonEncode
func JsonEncode(v interface{}) string {
	//将结构体转换为json字符串
	jsonStr, _ := json.Marshal(v)
	return string(jsonStr)
}

// 获取一个数组中角度差距最大的两个值，返回值和索引
func GetMaxAngleDiff(arr []float64) (float64, float64, int, int) {
	maxDiff := 0.0
	var angle1, angle2 float64
	var index1, index2 int
	for i, v := range arr {
		for j := i + 1; j < len(arr); j++ {
			//diff := math.Abs(v - arr[j])
			d1 := math.Abs(v - arr[j])
			d2 := 360 - d1
			//取最小值
			diff := math.Min(d1, d2)
			if diff > maxDiff {
				maxDiff = diff
				angle1 = v
				angle2 = arr[j]
				index1 = i
				index2 = j
			}
		}
	}
	return angle1, angle2, index1, index2
}

//	for k, vRange := range angleMap {
//		if v.WindAngle != "" {
//			if windAngle >= vRange[0] && windAngle < vRange[1] {
//				windAngleArr = append(windAngleArr, k)
//				break
//			}
//			if k == "N'" {
//				if (windAngle >= vRange[0] && windAngle < 360) || (windAngle >= 0 && windAngle < vRange[1]) {
//					windAngleArr = append(windAngleArr, k)
//					break
//				}
//			}
//		}
//	}
var angleMap = map[string][]float64{
	"E'": {67.5, 112.5},
	"NE": {22.5, 67.5},
	"N'": {337.5, 22.5},
	"NW": {292.5, 337.5},
	"W'": {247.5, 292.5},
	"SW": {202.5, 247.5},
	"S'": {157.5, 202.5},
	"SE": {112.5, 157.5},
}

// 根据角度获取方向
func GetAngleDirection(angle float64) string {
	for k, vRange := range angleMap {
		if angle >= vRange[0] && angle < vRange[1] {
			return k
		}
		if k == "N'" {
			if (angle >= vRange[0] && angle < 360) || (angle >= 0 && angle < vRange[1]) {
				return k
			}
		}
	}
	return ""
}
